package com.sc.study.clazz.service.impl;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.sc.common.core.domain.entity.SysUser;
import com.sc.common.core.text.Convert;
import com.sc.common.exception.ServiceException;
import com.sc.common.utils.DateUtils;
import com.sc.common.utils.StringUtils;
import com.sc.study.clazz.domain.ScClazzSubject;
import com.sc.study.clazz.domain.ScClazzSubjectTeacher;
import com.sc.study.clazz.mapper.ScClazzSubjectMapper;
import com.sc.study.clazz.mapper.ScClazzSubjectTeacherMapper;
import com.sc.study.foundation.domain.ScSubject;
import com.sc.study.foundation.domain.ScSubjectTeacher;
import com.sc.study.foundation.mapper.ScGradeMapper;
import com.sc.study.foundation.mapper.ScRoomMapper;
import com.sc.study.foundation.mapper.ScSubjectMapper;
import com.sc.study.foundation.mapper.ScSubjectTeacherMapper;
import com.sc.study.student.domain.ScStudent;
import com.sc.study.student.domain.ScStudentClazz;
import com.sc.study.student.domain.ScStudentSubject;
import com.sc.study.student.mapper.ScStudentClazzMapper;
import com.sc.study.student.mapper.ScStudentMapper;
import com.sc.study.student.mapper.ScStudentSubjectMapper;
import com.sc.system.mapper.SysUserMapper;
import com.sc.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sc.study.clazz.mapper.ScClazzMapper;
import com.sc.study.clazz.domain.ScClazz;
import com.sc.study.clazz.service.IScClazzService;

/**
 * 班级Service业务层处理
 *
 * @author sc
 * @date 2022-02-27
 */
@Service
public class ScClazzServiceImpl implements IScClazzService {
    @Autowired
    private ScClazzMapper scClazzMapper;
    @Autowired
    private ScStudentMapper scStudentMapper;
    @Autowired
    private ScStudentClazzMapper scStudentClazzMapper;
    @Autowired
    private ScStudentSubjectMapper scStudentSubjectMapper;
    @Autowired
    private ScGradeMapper scGradeMapper;
    @Autowired
    private ScClazzSubjectMapper scClazzSubjectMapper;
    @Autowired
    private ScClazzSubjectTeacherMapper scClazzSubjectTeacherMapper;
    @Autowired
    private ScSubjectMapper scSubjectMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ScSubjectTeacherMapper scSubjectTeacherMapper;
    @Autowired
    private ScRoomMapper scRoomMapper;
    @Autowired
    private ISysConfigService sysConfigService;

    /**
     * 查询班级包含学员和历史学员
     *
     * @param clazzId 班级主键
     * @return 班级
     */
    @Override
    public ScClazz selectScClazzByIdIncludeScStudent(Long clazzId) {
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));
        ScClazz clazz = scClazzMapper.selectScClazzById(clazzId);

        //查询班级包含本班学员
        clazz.setScStudentList(scStudentMapper.selectStudentInClazz(clazzId,studentCode));

        //查询到该班级的历史学员
        clazz.setScOldStudentList(scStudentMapper.selectOldStudentInClazz(clazzId,studentCode));

        //查询该班班主任
        if(clazz.getUserid()!=null){
            ScStudentClazz scStudentClazz = scStudentClazzMapper.selectScStudentClazzById(clazz.getUserid());
            clazz.setUser(sysUserMapper.selectUserById(scStudentClazz.getStudentid()));
        }


        return clazz;
    }


    /**
     * 查询班级包含学员和班级科目
     *
     * @param id 班级主键
     * @return 班级
     */
    @Override
    public ScClazz selectScClazzById(Long id) {
        Integer studentCode = Integer.valueOf(sysConfigService.selectConfigByKey("student_code"));
        ScClazz scClazz = scClazzMapper.selectInfo(id, studentCode);
        if(scClazz.getUserid()!=null){
            ScStudentClazz scStudentClazz = scStudentClazzMapper.selectScStudentClazzById(scClazz.getUserid());
            scClazz.setUser(sysUserMapper.selectUserById(scStudentClazz.getStudentid()));
        }

        return scClazz;
    }


    /**
     * 查询班级包含学员和班级科目
     */


    /**
     * 查询班级列表包含年级和教室
     *
     * @param scClazz 班级
     * @return 班级
     */
    @Override
    public List<ScClazz> selectScClazzList(ScClazz scClazz) {
        List<ScClazz> scClazzList = scClazzMapper.selectScClazzList(scClazz);
        scClazzList.forEach(item -> {
            item.setScGrade(scGradeMapper.selectScGradeById(item.getGradeid()));
            item.setScRoom(scRoomMapper.selectScRoomById(item.getRoomid()));
        });
        return scClazzList;
    }

    /**
     * 查询班级列表
     *
     * @param scClazz 班级
     * @return 班级
     */
    @Override
    public List<ScClazz> find(ScClazz scClazz) {
        return scClazzMapper.selectScClazzList(scClazz);
    }

    /**
     * 新增班级
     *
     * @param scClazz 班级
     * @return 结果
     */
    @Override
    public int insertScClazz(ScClazz scClazz) {
        //添加班级
        return insertScClazzMethod(scClazz);
    }

    /**
     * 添加班级 包括学员班级、学员科目、学员班级老师、班级科目老师、班级科目、修改学员班级id
     * @param scClazz
     */
    private Integer insertScClazzMethod(ScClazz scClazz) {
        int count = scClazzMapper.insertScClazz(scClazz);


        if (scClazz.getScStudentList().size() > 0) {
            scClazz.getScStudentList().forEach(scStudent -> {
                //增加学生与班级的关联
                insertScStudentClazzAndScSubjectAndScStudentSubject(scClazz,scStudent);
            });
        }
        insertTeacher(scClazz);
        insertScClazzSubjectAndScClazzSubjectTeacher(scClazz);

        return count;
    }


    /**
     * 修改班级
     *
     * @param scClazz 班级
     * @return 结果
     */
    @Override
    public int updateScClazz(ScClazz scClazz) {

        return scClazzMapper.updateScClazz(scClazz);
    }

    /**
     * 批量删除班级
     *
     * @param ids 需要删除的班级主键
     * @return 结果
     */
    @Override
    public int deleteScClazzByIds(Long[] ids) {
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));

        ScStudentClazz scStudentClazz = new ScStudentClazz();
        for (Long id : ids) {
            ScClazz scClazz = scClazzMapper.selectScClazzById(id);
            // 找到班级学员表查看是否有学员
            scStudentClazz.setClazzid(scClazz.getId());
            scStudentClazz.setClazzpersontypeid(studentCode);

            // 查询学员班级没离过班的
            List<ScStudentClazz> scStudentClazzList = scStudentClazzMapper.selectScStudentClazzList(scStudentClazz);
            if (scStudentClazzList.size() != 0) {
                throw new ServiceException("班级里还有学生，不能删除！");
            }
        }
            ScStudentClazz scStudentClazz1 = new ScStudentClazz();
            for (Long id : ids) {

                ScClazzSubject scClazzSubject = new ScClazzSubject();
                scClazzSubject.setClazzid(id);
                // 找到该班级对应的班级科目
                List<ScClazzSubject> scClazzSubjectList = scClazzSubjectMapper.selectScClazzSubjectList(scClazzSubject);

                scClazzSubjectList.forEach(item -> {
                    // 根据班级科目找到对应的班级授课老师进行删除
                    ScClazzSubjectTeacher scClazzSubjectTeacher = new ScClazzSubjectTeacher();
                    scClazzSubjectTeacher.setClazzsubid(item.getId());
                    scClazzSubjectTeacherMapper.deleteScClazzSubjectTeacher(scClazzSubjectTeacher);
                    // 删除班级对应的班级科目
                    scClazzSubjectMapper.deleteScClazzSubjectById(item.getId());
                });

                //删除班级里所有学员班级记录
                scStudentClazz1.setClazzid(id);
                scStudentClazzMapper.deleteScStudentClazz(scStudentClazz1);

            // 删除班级
            return scClazzMapper.deleteScClazzByIds(ids);
        }
        return 0;
    }

    /**
     * 删除班级信息
     *
     * @param id 班级主键
     * @return 结果
     */
    @Override
    public Integer deleteScClazzById(Long id) {
        return scClazzMapper.deleteScClazzById(id);
    }


    /**
     * 修改班级信息
     *
     * @param scClazz 班级对象
     * @return
     */
    @Override
    public int updateScClazzIncludeStudent(ScClazz scClazz) {
        ScStudentClazz scStudentClazz = new ScStudentClazz();
        scStudentClazz.setClazzid(scClazz.getId());
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));

        scStudentClazz.setClazzpersontypeid(studentCode);

        ScClazz scClazz1 = scClazzMapper.selectScClazzById(scClazz.getId());
        //
        ScStudentClazz scStudentClazz1 = scStudentClazzMapper.selectScStudentClazzById(scClazz1.getUserid());
        scStudentClazz1.setStudentid(scClazz.getUserid());
        scStudentClazzMapper.updateScStudentClazz(scStudentClazz1);

        // 根据班级找到对应的学员班级
        List<ScStudentClazz> scStudentClazzList = scStudentClazzMapper.selectScStudentClazzList(scStudentClazz);

        // 根据学员班级找到对应的学员
        scStudentClazzList.forEach(item -> {
            ScStudent scStudent = new ScStudent();
            scStudent.setId(item.getStudentid());
            // 将学员的学员班级编号修改为空
            scStudentMapper.updateScStudentStudentClazzId(scStudent);
            // 删除学员对应的学员科目
            ScStudentSubject scStudentSubject = new ScStudentSubject();
            scStudentSubject.setStudentid(item.getStudentid());
            scStudentSubjectMapper.deleteScStudentSubject(scStudentSubject);
        });

        // 删除班级里所有学员班级记录
        scStudentClazzMapper.deleteScStudentClazz(scStudentClazz);

        // 添加学员班级
        scClazz.getScStudentList().forEach(item -> {
            // 添加学员与班级的关联
            ScStudentClazz studentClazz = new ScStudentClazz(scClazz.getId(), item.getId(), scClazz.getGradeid(), studentCode, DateUtils.getLocalDateTime());
            scStudentClazzMapper.insertScStudentClazz(studentClazz);

            // 修改学员班级Id
            item.setStudentclazzid(studentClazz.getId());
            scStudentMapper.updateScStudent(item);

            // 添加学员对应的科目
            ScClazzSubject scClazzSubject = new ScClazzSubject();
            scClazzSubject.setClazzid(scClazz.getId());
            List<ScClazzSubject> clazzSubjectList = scClazzSubjectMapper.selectScClazzSubjectList(scClazzSubject);

            //循环添加学员科目信息
            clazzSubjectList.forEach(clazzSubject -> {
                clazzSubject.setScSubject(scSubjectMapper.selectScSubjectBySubid(clazzSubject.getSubid()));
                scStudentSubjectMapper.insertScStudentSubject(new ScStudentSubject(clazzSubject.getSubid(), item.getId(), clazzSubject.getScSubject().getSubtime(), 0L));
            });
        });

        // 找到班级对应的班级科目集合
        ScClazzSubject scClazzSubject = new ScClazzSubject();
        scClazzSubject.setClazzid(scClazz.getId());
        List<ScClazzSubject> scClazzSubjectList = scClazzSubjectMapper.selectScClazzSubjectList(scClazzSubject);
        scClazzSubjectList.forEach(item -> {
            // 根据班级科目找到对应的班级科目老师进行删除
            ScClazzSubjectTeacher scClazzSubjectTeacher = new ScClazzSubjectTeacher();
            scClazzSubjectTeacher.setClazzsubid(item.getId());
            scClazzSubjectTeacherMapper.deleteScClazzSubjectTeacher(scClazzSubjectTeacher);
        });
        // 根据班级删除班级科目
        scClazzSubjectMapper.deleteScClazzSubject(scClazzSubject);

        insertScClazzSubjectAndScClazzSubjectTeacher(scClazz);


        return scClazzMapper.updateScClazz(scClazz);
    }

    /**
     * 升学
     * @param scClazz 班级对象
     * @return
     */
    @Override
    public Integer enterHigherSchool(ScClazz scClazz) {
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));
        Long disabledState= Long.valueOf(sysConfigService.selectConfigByKey("disabled_state"));
        Long enableState= Long.valueOf(sysConfigService.selectConfigByKey("enable_state"));

        scClazz.setState(disabledState);
        //将原来班级的状态改为禁用
        scClazzMapper.updateScClazz(scClazz);

        scClazz.setState(enableState);
        int count = scClazzMapper.insertScClazz(scClazz);



        if (scClazz.getScStudentList().size() > 0) {
            ScStudentClazz scStudentClazz2=new ScStudentClazz();

            scClazz.getScStudentList().forEach(scStudent -> {
                //将该班级原来学员班级表里的数据设置为离班时间
                scStudentClazz2.setStudentid(scStudent.getId());
                scStudentClazz2.setClazzpersontypeid(studentCode);
                scStudentClazz2.setOuttime(DateUtils.getLocalDateTime());

                scStudentClazzMapper.updateScStudentClazzWrapper(scStudentClazz2);

                insertScStudentClazzAndScSubjectAndScStudentSubject(scClazz,scStudent);

            });
        }
        insertScClazzSubjectAndScClazzSubjectTeacher(scClazz);

        return Math.toIntExact(scClazz.getId());
    }


    /**
     * 循环科目 增加科目与班级的关联和班级科目与班级科目老师的关联
     *
     * @param scClazz 班级对象
     */
    private void insertScClazzSubjectAndScClazzSubjectTeacher(ScClazz scClazz) {
        if (scClazz.getScSubjectList().size() > 0) {
            //增加科目与班级的关联
            AtomicLong i = new AtomicLong(0);
            ScClazzSubject scClazzSubject = new ScClazzSubject();
            scClazzSubject.setClazzid(scClazz.getId());
            scClazzSubject.setSuborder(i.incrementAndGet());

            scClazz.getScSubjectList().forEach(scSubject -> {
                scClazzSubject.setSubid(scSubject.getSubid());
                scClazzSubject.setSubleftover(scSubject.getSubtime());
                scClazzSubjectMapper.insertScClazzSubject(scClazzSubject);

                Optional<Long> optionalUserId = Optional.ofNullable(scSubject.getUserId());
                // 是否存在userId 如果有就继续
                optionalUserId.ifPresent(userId -> {
                    //增加班级科目与班级科目老师的关联
                    ScClazzSubjectTeacher scClazzSubjectTeacher = new ScClazzSubjectTeacher(scClazzSubject.getId(), scSubject.getUserId(), 0L, DateUtils.getLocalDateTime());
                    scClazzSubjectTeacherMapper.insertScClazzSubjectTeacher(scClazzSubjectTeacher);
                });
            });
        }
    }

    /**
     * 添加学员班级、学员、学员科目、修改学员班级id
     * @param scClazz
     * @param scStudent
     */
    private void insertScStudentClazzAndScSubjectAndScStudentSubject(ScClazz scClazz,ScStudent scStudent){
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));

        //增加学生与班级的关联
        ScStudentClazz scStudentClazz = new ScStudentClazz(scClazz.getId(), scStudent.getId(), scClazz.getGradeid(), studentCode, DateUtils.getLocalDateTime());
        scStudentClazzMapper.insertScStudentClazz(scStudentClazz);

        //修改学员班级Id
        scStudent.setStudentclazzid(scStudentClazz.getId());
        scStudentMapper.updateScStudent(scStudent);



        //循环添加学员科目信息
        if (scClazz.getScSubjectList().size() > 0) {
            //增加科目与学员的关联
            scClazz.getScSubjectList().forEach(scSubject -> {
                scStudentSubjectMapper.insertScStudentSubject(new ScStudentSubject(scSubject.getSubid(), scStudent.getId(), scSubject.getSubtime(), 0L));
            });
        }
    }

    /**
     * 添加班主任
     * @param scClazz
     */
    private void insertTeacher(ScClazz scClazz){
        int teacherCode = Integer.parseInt(sysConfigService.selectConfigByKey("bzr_teacher_type"));
        //增加班主任与班级的关联
        ScStudentClazz scStudentClazz1 = new ScStudentClazz(scClazz.getId(), scClazz.getUserid(), scClazz.getGradeid(), teacherCode, DateUtils.getLocalDateTime());
        scStudentClazzMapper.insertScStudentClazz(scStudentClazz1);

        //修改班主任人员班级id
        scClazz.setUserid(scStudentClazz1.getId());
        scClazzMapper.updateScClazz(scClazz);
    }
}
